#ifndef _KC_PARSER_IMPL__H___KC_2008_
#define _KC_PARSER_IMPL__H___KC_2008_

#include <iostream>
#include <string>
#include <stack>
#include <memory>
#include "Token.h"
#include "TokenCollection.h"
#include "Yystype.h"

#undef yyFlexLexer
#include <FlexLexer.h>

#ifndef YYSTYPE
	#define YYSTYPE yystype_struct
#endif

namespace yy
{
	class BisonParser;
}

using namespace kc_sf;

class FlexScanner : public yyFlexLexer
{
    public:
    
        explicit FlexScanner( std::istream *in, 
                              std::ostream *out = NULL );
        ~FlexScanner();
                        
        int readInput( char *buffer, int max_size );    // czyta do bufora flexa max_size bajtow ze strumienia wejsciowego        
                      
        unsigned int linesRead() const;                 // zwraca liczbę odczytanych linii
        unsigned int bytesRead() const;                 // zwraca liczbę odczytanych bajtów
        std::string  lastlineRead() const;              // zwraca ostatnio odczytaną linię w formie napisu

        int newToken( yystype_struct *yystype,          // ustawia składowe tokenu stworzonego przez lekser
                      const char * const &value,        // i uzupełnia hierarchię tokenów tokens
                      int type );

        void error() const;                             // informacja o położeniu błędzu w strumieniu wejściowym

        // flex w c++
        int scan( YYSTYPE *new_token ); //{ return yy_scanner.yylex(); }
		friend class yy::BisonParser;

    private:
    
        // wejście
        std::istream    *fs_input;                      // uchwyt do strumienia bajtow wiadomości odebranej przez moduł odbierający
        
        // przetwarzanie
        char            *fs_last_line;                  // ostatnio przetwarzana linia ze strumienia wiadomosci ( wieksza niz 80 znakow na wypadek niepoprawnych wiadomosci )
        int             fs_last_line_length;            // dlugosc tego fragmentu linii wejscia, która nie zmiescila sie w buforze skanera
        
        unsigned int    fs_lines;                       // liczba odczytanych linii
        unsigned int    fs_bytes_in_line;               // liczba odczytanych znaków ( bajtów ) w ostatniej linii
        unsigned int    fs_bytes;                       // liczba odczytanych znaków ( bajtów ) od początku tekstu ( strumienia )
        unsigned int    fs_last_entity_start;           // pozycja w strumieniu, od której zaczeła się ostatnio przetworzona encja
            
        // wyjście
        TokenCollection fs_tokens;                      // uchwyt do kolekcji tokenów, przechowującej (w kolejności tworzenia) tokeny wygenerowane przez skaner        
        std::stack<std::string> fs_specials;			// zapamietuje specjalne wartosci, np. boundary

        TokenCollection::const_iterator tokensEnd() const; 	  // ostatni rozpoznany token
        TokenCollection::const_iterator lastToken() const; 	  // ostatni rozpoznany token
};

#endif // _KC_PARSER_IMPL__H___KC_2008_
